package com.cswangdao.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.cswangdao.domain.dto.CouponPageDTO;
import com.cswangdao.domain.dto.CouponUserPageDTO;
import com.cswangdao.domain.model.MarketCart;
import com.cswangdao.domain.model.MarketCoupon;
import com.cswangdao.domain.model.MarketCouponUser;
import com.cswangdao.domain.po.Coupon;
import com.cswangdao.domain.vo.AvailableCouponVo;
import com.cswangdao.mapper.MarketCartMapper;
import com.cswangdao.mapper.MarketCouponMapper;
import com.cswangdao.mapper.MarketCouponUserMapper;
import com.cswangdao.result.PageResult;
import com.cswangdao.service.CouponService;

import com.cswangdao.utils.CouponUtil;
import com.cswangdao.utils.SubjectUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;

@Service
@Transactional
public class CouponServletImpl implements CouponService {

    @Autowired
    private MarketCouponMapper couponMapper;

    @Autowired
    private MarketCouponUserMapper couponUserMapper;


    @Autowired
    private MarketCartMapper cartMapper;

    @Autowired
    private CouponUtil couponUtil;


    /**
     * @description: 分页查询优惠卷信息
     * @param: couponPageDTO
     * @return: com.cswangdao.result.PageResult<com.cswangdao.domain.po.Coupon>
     */
    @Override
    public PageResult<Coupon> pageQueryInfo(CouponPageDTO couponPageDTO) {
        try {
            PageHelper.startPage(couponPageDTO.getPage(), couponPageDTO.getLimit());
            Page<Coupon> couponPage = couponMapper.pageQueryInfo(couponPageDTO);
            PageResult<Coupon> result = PageResult.result(couponPage);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    /**
     * @description: 新增优惠卷信息
     * @param: coupon
     * @return: com.cswangdao.domain.po.Coupon
     */
    @Override
    public Coupon addCoupon(Coupon coupon) {
        try {
            Date now = new Date();
            coupon.setAddTime(now);
            coupon.setUpdateTime(now);
            if (coupon.getDays() == null) {
                coupon.setDays((short) 0);
            }
            couponMapper.insert(coupon);
            Coupon res = couponMapper.selectById(coupon.getId());
            return res;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public Coupon updateById(Coupon coupon) {
        try {
            if (coupon.getDays() == null) {
                coupon.setDays((short) 0);
            }
            coupon.setUpdateTime(new Date());
            couponMapper.updateById(coupon);
            return coupon;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public void deleteById(Integer id) {
        try {
            couponMapper.deleteById(id);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public PageResult<MarketCouponUser> getCouponUserList(CouponUserPageDTO pageDTO) {
        try {
            PageHelper.startPage(pageDTO.getPage(), pageDTO.getLimit());
            Page<MarketCouponUser> couponUserPage = couponUserMapper.pageQueryInfo(pageDTO);
            PageResult<MarketCouponUser> result = PageResult.result(couponUserPage);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public Coupon queryById(int i) {
        Coupon coupon = couponMapper.queryById(i);
        return coupon;
    }

    @Override
    public void receiveCoupon(Map params) {
        //获取优惠卷Id
        int couponId = Integer.parseInt(params.get("couponId").toString());
        // TODO 用户ID
        MarketCoupon coupon = couponMapper.getById(couponId);
        if (Objects.isNull(coupon)) {
            throw new RuntimeException("优惠卷不存在");
        }
        if (coupon.getLimit() == 0) {
            addCouponUser(1, coupon);
            return;
        }
        if (coupon.getLimit() == 1) {
            List<Integer> couponIds = couponUserMapper.getCouponIdsByUserId(1);
            if (CollUtil.isEmpty(couponIds) || !couponIds.contains(couponId)) {
                Integer total = coupon.getTotal();
                if (total > 0) {
                    couponMapper.reduceTotal(coupon.getId(), total - 1);
                    addCouponUser(1, coupon);
                    return;
                }
                throw new RuntimeException("优惠卷已领完");
            }
            throw new RuntimeException("你已经领取过该优惠卷");

        }
        throw new RuntimeException("优惠卷状态异常");

    }

    @Override
    public PageResult<MarketCoupon> myCoupons(short status, int page, int limit) {
        // TODO 用户ID
        List<MarketCouponUser> couponUserList = couponUserMapper.getCouponByUserId(1);
        if (couponUserList.isEmpty()) {
            throw new RuntimeException("没有优惠卷");
        }
        List<Integer> couponIds = couponUserList.stream()
                .filter(o->o.getStatus().equals(status))
                .map(MarketCouponUser::getCouponId)
                .toList();
        if(CollUtil.isEmpty(couponIds)){
            return null;
        }
        PageHelper.startPage(page, limit);
        Page<MarketCoupon> couponPage = couponMapper.getMyCoupons(couponIds);
        PageResult<MarketCoupon> result = PageResult.result(couponPage);
        return result;
    }

    @Override
    public PageResult<AvailableCouponVo> selectAvailableCoupons(int cartId) {
        BigDecimal goodsTotalPrice = BigDecimal.ZERO;
        // 购物车查询货品总金额
        if (cartId == 0) {
            // TODO 用户ID
            List<MarketCart> cartList = cartMapper.getCartListByUserId(1);
            goodsTotalPrice = cartList.stream()
                    .filter(MarketCart::getChecked)
                    .map(o -> o.getPrice().multiply(BigDecimal.valueOf(o.getNumber())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            //立即购买
        } else if (cartId > 0) {
            MarketCart cart = cartMapper.getById(cartId);
            if (Objects.isNull(cart)) {
                throw new RuntimeException("购物车不存在");
            }
            goodsTotalPrice = cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber()));
        }
        // TODO 用户ID
        // 查询可用优惠卷
        List<MarketCouponUser> couponUsers = couponUtil.availableCoupons(1, goodsTotalPrice);
        if (CollUtil.isEmpty(couponUsers)) {
            return null;
        }
        // 查询可用优惠卷Id
        List<Integer> couponIds = couponUsers.stream().map(MarketCouponUser::getCouponId).toList();
        // 查询可用优惠卷信息
        List<AvailableCouponVo> availableCouponVos = couponMapper.getAvailableCouponsByIds(couponIds);

        PageResult<AvailableCouponVo> res = PageResult.builder()
                .limit(availableCouponVos.size())
                .pages(1)
                .page(1)
                .total((long) availableCouponVos.size())
                .list((List) availableCouponVos)
                .build();
        return res;
    }

    @Override
    public void exchangeCoupon(String code) {
        //获取优惠券信息
       MarketCoupon coupon = couponMapper.getCouponByCode(code);
       //判断优惠卷是否存在
        if(Objects.isNull(coupon)){
        //不存在，抛出异常
            throw new RuntimeException("优惠卷不存在");
        }
        //存在
        if(coupon.getTotal() <= 0){
           throw new RuntimeException("优惠卷已领完");
        }
        MarketCouponUser couponUser = couponUserMapper.getByUserIdAndCouponId(SubjectUtil.getUserId(), coupon.getId());
        if(Objects.nonNull(couponUser)){
            throw new RuntimeException("你已经领取过该优惠卷");
        }
        //减去优惠卷库存
        couponMapper.reduceTotal(coupon.getId(),coupon.getTotal()-1);
        //增加优惠卷用户信息
        addCouponUser(SubjectUtil.getUserId(),coupon);
    }

    @Override
    public PageResult<MarketCoupon> allCoupons(int page,int limit) {
        PageHelper.startPage(page, limit);
        Page<MarketCoupon> coupons =couponMapper.selectAll((short) 0);
        List<MarketCoupon> list = coupons.getResult().stream().filter(new Predicate<MarketCoupon>() {
            @Override
            public boolean test(MarketCoupon coupon) {
                Short timeType = coupon.getTimeType();
                if (timeType.equals((short) 1)) {
                    Date now = new Date();
                    if (coupon.getEndTime().before(now)) {
                        return false;
                    }
                    if (coupon.getStartTime().after(now)) {
                        return false;
                    }
                }
                return true;
            }
        }).toList();
        return PageResult.builder()
                .total((long) list.size())
                .page(page)
                .limit(limit)
                .list((List) list)
                .pages(coupons.getPages())
                .build();
    }

    private void addCouponUser(int userId, MarketCoupon coupon) {

        MarketCouponUser couponUser = MarketCouponUser.builder()
                .userId(userId)
                .couponId(coupon.getId())
                .addTime(new Date())
                .updateTime(new Date())
                .status((short) 0)
                .startTime(coupon.getStartTime())
                .endTime(coupon.getEndTime())
                .build();
        couponUserMapper.addCouponUser(couponUser);
    }
}
